package demo.log4j2;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.appender.AsyncAppender;
import org.apache.logging.log4j.core.appender.ConsoleAppender;
import org.apache.logging.log4j.core.appender.FailoverAppender;
import org.apache.logging.log4j.core.appender.FileAppender;
import org.apache.logging.log4j.core.appender.RandomAccessFileAppender;
import org.apache.logging.log4j.core.appender.RollingFileAppender;
import org.apache.logging.log4j.core.appender.RollingRandomAccessFileAppender;
import org.apache.logging.log4j.core.async.AsyncLoggerContextSelector;
import org.apache.logging.log4j.core.async.BasicAsyncLoggerContextSelector;
import org.apache.logging.log4j.core.async.RingBufferLogEvent;
import org.apache.logging.log4j.core.impl.Log4jLogEvent;
import org.apache.logging.log4j.core.impl.MutableLogEvent;
import org.apache.logging.log4j.core.osgi.BundleContextSelector;
import org.apache.logging.log4j.core.selector.BasicContextSelector;
import org.apache.logging.log4j.core.selector.ClassLoaderContextSelector;
import org.apache.logging.log4j.core.selector.ContextSelector;
import org.apache.logging.log4j.core.selector.JndiContextSelector;

import java.io.Console;

/**
 * Log4j 2 包含了基于LMAX 分离库的下一代的异步日志系统
 */
public class Log4j2Test {

    /**
     * 主要区别总结：
     *
     * <p>可变性：
     *
     * <li>Log4jLogEvent：不可变
     * <li>MutableLogEvent：可变
     * <li>RingBufferLogEvent：设计用于异步操作，内部状态可变
     *
     * <p>使用场景：
     *
     * <li>Log4jLogEvent：一般用途
     * <li>MutableLogEvent：高性能场景，对象重用
     * <li>RingBufferLogEvent：异步高性能场景
     *
     * <p>性能考虑：
     *
     * <li>Log4jLogEvent：每次创建新对象，可能增加GC压力
     * <li>MutableLogEvent：通过重用减少对象创建，降低GC压力
     * <li>RingBufferLogEvent：设计用于高吞吐量，低延迟场景
     *
     * <p>线程安全：
     *
     * <li>Log4jLogEvent：由于不可变，天然线程安全
     * <li>MutableLogEvent：在多线程环境下需要小心使用
     * <li>RingBufferLogEvent：设计用于特定的异步处理模式
     */
    public void logEvent(LogEvent logEvent) {
        /**
         * Log4jLogEvent:
         * <li>这是最基本和最常用的LogEvent实现。
         * <li>它是不可变的（immutable），意味着一旦创建就不能修改。
         * <li>适用于大多数日志记录场景。
         * <li>每次日志操作都会创建一个新的实例。
         */
        Log4jLogEvent log4jLogEvent = new Log4jLogEvent();

        /**
         * MutableLogEvent
         * <li>这是一个可变（mutable）的LogEvent实现。
         * <li>设计用于重用对象，以减少垃圾收集的压力。
         * <li>适用于高性能场景，特别是在使用异步日志记录时。
         * <li>可以被重置和重用，而不是每次都创建新实例。
         * <li>需要小心使用，因为它的状态可能会被修改。
         */
        MutableLogEvent mutableLogEvent = new MutableLogEvent();

        /**
         * RingBufferLogEvent
         * <li>专门为异步日志记录设计。
         * <li>与Disruptor库一起使用，用于高性能、低延迟的日志记录。
         * <li>在内部使用环形缓冲区（Ring Buffer）来存储日志事件。
         * <li>适用于需要极高吞吐量的场景。
         */
        RingBufferLogEvent ringBufferLogEvent = new RingBufferLogEvent();
    }

    /**
     * 在Appender中定义可选的输出“目的地”
     */
    public void appender() {
        Appender appender = null;
        ConsoleAppender consoleAppender = null;
        FileAppender fileAppender = null;
        RandomAccessFileAppender randomAccessFileAppender = null;
        RollingFileAppender rollingFileAppender = null;
        RollingRandomAccessFileAppender rollingRandomAccessFileAppender = null;
        AsyncAppender asyncAppender = null;

        FailoverAppender failoverAppender = null;
    }

    public void contextSelector(ContextSelector contextSelector) {
        // Creates a separate logger context per classloader and synchronous loggers
        ClassLoaderContextSelector classLoaderContextSelector = null;

        // Creates a single logger context and synchronous loggers
        BasicContextSelector basicContextSelector = null;

        // This will create a single logger context and disruptor for all the classes in the JVM,
        BasicAsyncLoggerContextSelector basicAsyncLoggerContextSelector = null;

        // Creates a separate logger context per classloader and asynchronous loggers
        AsyncLoggerContextSelector asyncLoggerContextSelector = null;

        // Creates a separate logger context per OSGi bundle and synchronous loggers
        BundleContextSelector bundleContextSelector = null;

        // Creates loggers contexts based on a JNDI lookup and synchronous loggers See Web application for details.
        JndiContextSelector jndiContextSelector = null;
    }

    /**
     * <a href="https://blog.csdn.net/yuanmintao/article/details/134515268">log4j2异步日志</a>
     *
     * 异步日志依赖：com.lmax:disruptor
     * <li>方式1：在classpath，比如resources目录下，新建log4j2.component.properties配置文件。
     * 内容如下：Log4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
     * <li>方式2：ROOT LOGGER改为异步：Root -> AsyncRoot
     */
    public void asyncLog(){

    }


}
